<template>
    <span
      tabindex="0"
      :class="wrapClasses"
      @click="toggle"
      @keydown.space="toggle"
    >
        <input type="hidden" :name="name" :value="currentValue">
        <span :class="innerClasses">
            <slot name="open" v-if="currentValue === trueValue"></slot>
            <slot name="close" v-if="currentValue === falseValue"></slot>
        </span>
    </span>
</template>
<script>
import {oneOf} from '../../utils/assist';
import Emitter from '../../mixins/emitter';

const prefixCls = 'oolong-switch';

export default {
  name: 'oolongSwitch',
  mixins: [Emitter],
  props: {
    value: {
      type: [String, Number, Boolean],
      default: false
    },
    trueValue: {
      type: [String, Number, Boolean],
      default: true
    },
    falseValue: {
      type: [String, Number, Boolean],
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    size: {
      validator(value) {
        return oneOf(value, ['large', 'small', 'default']);
      }
    },
    name: {
      type: String
    }
  },
  data() {
    return {
      currentValue: this.value
    };
  },
  computed: {
    wrapClasses() {
      return [
        `${prefixCls}`,
        {
          [`${prefixCls}-checked`]: this.currentValue === this.trueValue,
          [`${prefixCls}-disabled`]: this.disabled,
          [`${prefixCls}-${this.size}`]: !!this.size
        }
      ];
    },
    innerClasses() {
      return `${prefixCls}-inner`;
    }
  },
  methods: {
    toggle(event) {
      event.preventDefault();
      if (this.disabled) {
        return false;
      }

      const checked = this.currentValue === this.trueValue ? this.falseValue : this.trueValue;

      this.currentValue = checked;
      this.$emit('input', checked);
      this.$emit('on-change', checked);
      this.dispatch('oolongFormItem', 'on-form-change', checked);
    }
  },
  watch: {
    value(val) {
      if (val !== this.trueValue && val !== this.falseValue) {
        // eslint-disable-next-line no-throw-literal
        throw 'Value should be trueValue or falseValue.';
      }
      this.currentValue = val;
    }
  }
};
</script>
